package org.jing.ext.windows;

import org.jing.core.lang.JingException;
import org.jing.core.util.FileUtil;
import org.jing.core.util.StringUtil;

import java.io.File;

/**
 * Description: <br>
 *
 * @author bks <br>
 * @since 2023-02-24 <br>
 */
public class WinRar {
    private Application application;

    private WinRar() {
    }

    private static void checkEnable(File appFile) {
        if (null == appFile) {
            throw new JingException("application haven't defined");
        }
        if (!appFile.exists() || !appFile.isFile()) {
            throw new JingException("invalid application: {}", appFile.getAbsolutePath());
        }
    }

    public static <T> T create(String appFilePath, Class<T> model) {
        return create(new File(appFilePath), model);
    }

    @SuppressWarnings("unchecked")
    public static <T> T create(File appFile, Class<T> model) {
        checkEnable(appFile);
        if (null == model) {
            throw new JingException("empty mode chosen");
        }
        if (model == Compress.class) {
            return (T) new Compress(appFile);
        }
        else if (model == Decompress.class) {
            return (T) new Decompress(appFile);
        }
        else {
            throw new JingException("invalid model chosen: {}", model);
        }
    }

    public static class Compress {
        private File appFile;

        private Compress(File appFile) {
            this.appFile = appFile;
        }
    }

    public static class Decompress {
        private File appFile;

        private boolean override = true;

        private File srcFile;

        private File destDirectory;

        private String password;

        private Decompress(File appFile) {
            this.appFile = appFile;
        }

        public boolean isOverride() {
            return override;
        }

        public void setOverride(boolean override) {
            this.override = override;
        }

        public File getSrcFile() {
            return srcFile;
        }

        public void setSrcFile(File srcFile) {
            this.srcFile = srcFile;
        }

        public void setSrcFile(String srcFilePath) {
            this.srcFile = new File(srcFilePath);
        }

        public File getDestDirectory() {
            return destDirectory;
        }

        public void setDestDirectory(File destDirectory) {
            this.destDirectory = destDirectory;
        }

        public void setDestDirectory(String destDirectoryPath) {
            this.destDirectory = new File(destDirectoryPath);
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public boolean execute() {
            checkEnable();
            Application application = new Application(appFile.getAbsolutePath());
            application.addParam("x").addParam("-o").addParam("-y").addParam("-ibck");
            if (StringUtil.isNotEmpty(password)) {
                application.addParam("-p" + password);
            }
            application.addParam("\"" + srcFile.getAbsolutePath() + "\"");
            application.addParam("\"" + destDirectory.getAbsolutePath() + "\"");
            return application.execute();
        }

        private void checkEnable() {
            if (null == srcFile) {
                throw new JingException("undefined source file");
            }
            else if (!srcFile.exists()) {
                throw new JingException("source file not exists: {}", srcFile.getAbsolutePath());
            }
            else if (!srcFile.isFile()) {
                throw new JingException("invalid source file: {}", srcFile.getAbsolutePath());
            }
            if (null == destDirectory) {
                destDirectory = srcFile.getParentFile();
            }
            else if (!FileUtil.mkdirs(destDirectory)) {
                throw new JingException("failed to create dest directory: {}", destDirectory.getAbsolutePath());
            }
        }
    }

    public static void main(String[] args) {
        Decompress decompress = WinRar.create("D:\\Program Files\\WinRAR\\WinRAR.exe", Decompress.class);
        decompress.setSrcFile("temp\\temp.zip.001");
        decompress.setDestDirectory("temp\\output");
        decompress.setPassword("farmer");
        System.out.println(decompress.execute());
    }
}
